﻿using UnityEngine;

public static partial class Utility
{

    /// <summary>
    /// 控件工具库
    /// </summary>
    public static class Component
    {

        /// <summary>
        /// 具体游戏用的 GetComponent
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="gameObject"></param>
        /// <returns></returns>
        public static T GetGameComponent<T>(GameObject gameObject) where T : UnityEngine.Component
            => GetGameComponent<T>(gameObject.transform);

        /// <summary>
        /// 具体游戏用的 GetComponent
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="transform"></param>
        /// <returns></returns>
        public static T GetGameComponent<T>(Transform transform) where T : UnityEngine.Component
        {
            if (transform == null)
                return null;
            var component = transform.GetComponent<T>();
            if (component != null)
            {
                GameMonoBehaviour behaviour = component as GameMonoBehaviour;
                if (behaviour != null)
                {
                    behaviour.InitBehaviour();
                    return (T)(behaviour as object);
                }
            }
            return component;
        }

        /// <summary>
        /// 具体游戏用的 GetComponentsInChildren
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="transform"></param>
        /// <returns></returns>
        public static T[] GetGameComponentsInChildren<T>(GameObject gameObject) where T : UnityEngine.Component
            => GetGameComponentsInChildren<T>(gameObject.transform);

        /// <summary>
        /// 具体游戏用的 GetComponentsInChildren
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="transform"></param>
        /// <returns></returns>
        public static T[] GetGameComponentsInChildren<T>(Transform transform) where T : UnityEngine.Component
        {
            if (transform == null)
                return null;
            T[] behaviours = transform.GetComponentsInChildren<T>();
            for (int i = 0, cnt = behaviours.Length; i < cnt; i++)
            {
                var t = behaviours[i];
                GameMonoBehaviour behaviour = t as GameMonoBehaviour;
                behaviour.InitBehaviour();
            }
            return behaviours;
        }

        public static T GetGameComponentInParent<T>(GameObject gameObject) where T : UnityEngine.Component
        {
            while (true)
            {
                T component = gameObject.GetComponent<T>();
                if (component != null)
                {
                    return component;
                }
                gameObject = gameObject.transform.parent?.gameObject;
                if (gameObject == null)
                {
                    return default(T);
                }
            }
        }


        public static T GetChildGameComponentByName<T>(Transform transform, string name) where T : UnityEngine.Component
        {
            T[] allChilds = transform.GetComponentsInChildren<T>(true);

            foreach (T child in allChilds)
            {
                if (child.name.Equals(name))
                {
                    GameMonoBehaviour behaviour = child as GameMonoBehaviour;
                    if (behaviour != null)
                    {
                        behaviour.InitBehaviour();
                    }
                    return child;
                }
            }
            return null;
        }

        /// <summary>
        /// 查找 GameObject 下指定路径的组件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="gameObject"></param>
        /// <param name="path">gameObject 下指定路径</param>
        /// <returns></returns>
        public static T FindGameComponent<T>(GameObject gameObject, string path) where T : UnityEngine.Component
            => FindGameComponent<T>(gameObject.transform, path);

        /// <summary>
        /// 查找 Transform 下指定路径的组件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="transform"></param>
        /// <param name="path">Transform 下指定路径</param>
        /// <returns></returns>
        public static T FindGameComponent<T>(Transform transform, string path) where T : UnityEngine.Component
        {
            if (!path.IsNullOrEmpty())
            {
                transform = transform.Find(path);
            }
            return GetGameComponent<T>(transform);
        }

        /// <summary>
        /// 添加组件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="gameObject"></param>
        /// <returns></returns>
        public static T AddGameComponent<T>(GameObject gameObject) where T : UnityEngine.Component
        {
            return gameObject.AddComponent<T>();
        }

        /// <summary>
        /// 获取或者添加组件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="gameObject"></param>
        /// <returns></returns>
        public static T GetOrAddComponent<T>(GameObject gameObject) where T : UnityEngine.Component
        {
            T comp = gameObject.GetGameComponent<T>();
            if (comp is null)
            {
                comp = gameObject.AddGameComponent<T>();
            }
            return comp;
        }

        /// <summary>
        /// 获取或者添加 GameObject 下指定路径的组件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="gameObject"></param>
        /// <param name="path">gameObject 下指定路径</param>
        /// <returns></returns>
        public static T GetOrAddComponent<T>(GameObject gameObject, string path) where T : UnityEngine.Component
            => GetOrAddComponent<T>(gameObject.transform, path);

        /// <summary>
        /// 获取或者添加 Transform 下指定路径的组件
        /// </summary>
        /// <typeparam name="T"><组件类型/typeparam>
        /// <param name="transform"></param>
        /// <param name="path">transform 下指定路径</param>
        /// <returns></returns>
        public static T GetOrAddComponent<T>(Transform transform, string path) where T : UnityEngine.Component
        {
            Transform trans = FindGameComponent<Transform>(transform, path);
            if (trans is null)
            {
                Logger.LogError("查找路径上的 Transform 为 null");
            }
            return GetOrAddComponent<T>(trans.gameObject);
        }


        public static void SetCanvasActive(GameObject go, bool isActive)
        {
            CanvasGroup canvasGroup = go.GetOrAddGameComponent<CanvasGroup>();
            if (canvasGroup != null)
            {
                canvasGroup.SetActive(isActive);
            }
        }

       
    }
}
